package net.lastcoder.ifserver.terminate;

import net.lastcoder.ifserver.nio.Connection;
import net.lastcoder.ifserver.packet.Packet;
import net.lastcoder.ifserver.session.Session;
import net.lastcoder.ifserver.session.UlaID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * auth: WenYF
 * date: 2016/11/23
 */
public class TerminateSession implements Session {
    private static final Logger Log = LoggerFactory.getLogger(TerminateSession.class);

    private UlaID uid;

    protected int status = STATUS_CONNECTED;

    protected Connection conn;

    private long startDate = System.currentTimeMillis();
    private Date createDate;

    private long lastActiveDate;
    private long clientPacketCount = 0;
    private long serverPacketCount = 0;

    private boolean initialized;
    private int presence = 0;

    private String name;

    private final Map<String, Object> sessionData = new HashMap<>();

    private TerminateSession(Connection conn, UlaID uid) {
        this.conn = conn;
        this.uid = uid;
        clientPacketCount = 0;
        serverPacketCount = 0;
        createDate = new Date();
        lastActiveDate = System.currentTimeMillis();
        name = uid.getUsername();
    }

    public static TerminateSession createSession(Connection conn, UlaID uid) {
        TerminateSession session = new TerminateSession(conn, uid);
        return session;
    }

    public void incrementClientPacketCount() {
        clientPacketCount++;
    }

    @Override
    public String getUsername() {
        return uid.getUsername();
    }

    public boolean isInitialized() {
        return initialized;
    }

    public void setInitialized(boolean isInit) {
        initialized = isInit;
    }

    public int getPresence() {
        return presence;
    }

    public void setPresence(int presence) {
        this.presence = presence;
    }

    @Override
    public UlaID getAddress() {
        return uid;
    }

    @Override
    public int getStatus() {
        return status;
    }

    @Override
    public Date getCreationDate() {
        return createDate;
    }

    @Override
    public Date getLastActiveDate() {
        return new Date(lastActiveDate);
    }

    @Override
    public long getNumClientPackets() {
        return clientPacketCount;
    }

    @Override
    public long getNumServerPackets() {
        return serverPacketCount;
    }

    @Override
    public void close() {
        this.status = STATUS_CLOSED;
        conn.close();
    }

    @Override
    public boolean isClosed() {
        return status == STATUS_CLOSED;
    }

    @Override
    public String getHostAddress() throws UnknownHostException {
        return conn.getHostAddress();
    }

    @Override
    public String getHostName() throws UnknownHostException {
        return conn.getHostName();
    }

    @Override
    public void deliverRawData(byte[] data) {
        serverPacketCount++;
        conn.deliverRawData(data);
    }

    @Override
    public void deliverRawData(byte[] data, int off, int len) {
        serverPacketCount++;
        conn.deliverRawData(data, off, len);
    }

    @Override
    public void process(Packet packet) {
        serverPacketCount++;
        conn.deliver(packet);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public int getConflictCount() {
        return 0;
    }

    @Override
    public Object getAttribute(String key) {
        return sessionData.get(key);
    }

    @Override
    public void setAttribute(String key, Object object) {
        sessionData.put(key, object);
    }

    @Override
    public Connection getConnection() {
        return conn;
    }

    @Override
    public void setStatus(int status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "ClientSession{" +
                "uid=" + uid +
                ", status=" + status +
                ", conn=" + conn +
                ", startDate=" + new Date(startDate) +
                ", createDate=" + createDate +
                ", lastActiveDate=" + new Date(lastActiveDate) +
                ", clientPacketCount=" + clientPacketCount +
                ", serverPacketCount=" + serverPacketCount +
                ", initialized=" + initialized +
                ", presence=" + presence +
                ", name='" + name + '\'' +
                ", sessionData=" + sessionData +
                '}';
    }
}
